import requests
import execjs
import time
from bs4 import BeautifulSoup
import re
import json

from PIL import Image

def get_shuffle_indices():
    e = [int(x) for x in "6_11_7_10_4_12_3_1_0_5_2_9_8".split('_')]
    t = []
    for r in range(52):
        n = 2 * e[int((r % 26) / 2)] + (r % 2)
        if (int(r / 2) % 2) != 0:
            n += -1 if (r % 2) else 1
        if r < 26:
            n += 26
        t.append(n)
    return t

def restore_bg(shuffled_img_path, restored_img_path="restored_bg.jpg"):
    # 1. 打开乱序图
    im = Image.open(shuffled_img_path)
    w, h = im.size
    slice_w, slice_h = 12, 80
    row_cnt = 2
    col_cnt = 26

    # 2. 得到shuffle索引（长度52）
    t = get_shuffle_indices()

    # 3. 分块剪切
    blocks = []
    for idx in range(52):
        row = idx // 26
        col = idx % 26
        left = col * slice_w
        top = row * slice_h
        crop = im.crop((left, top, left + slice_w, top + slice_h))
        blocks.append(crop)

    # 4. 按t新顺序拼接回原图
    new_im = Image.new('RGB', (w, h))
    for idx, block_idx in enumerate(t):
        row = idx // 26
        col = idx % 26
        left = col * slice_w
        top = row * slice_h
        new_im.paste(blocks[block_idx], (left, top))

    new_im.save(restored_img_path)
    print(f"还原后已保存: {restored_img_path}")





with open("enc2.js", "r", encoding="utf-8") as f:
    js_code = f.read()
ctx = execjs.compile(js_code)


def parse_validata_response(response_text):
    """
    解析 validata 响应，自动识别无感或滑块结果并统一返回结构化信息
    :param response_text: jsonp格式
    :return: dict 结构
    """
    # 1. 提取json包裹体（cb(...))）
    match = re.search(r'cb\((\{.*\})\)', response_text, re.DOTALL)
    if not match:
        raise ValueError("找不到有效的JSONP内容")
    data = json.loads(match.group(1))
    # 2. ReturnCode判断
    if data.get('ReturnCode') == '5':
        return {
            'type': 'noclick',
            'code': 5,
            'msg': data.get('Msg', ''),
            'data': None
        }
    elif data.get('ReturnCode') == '0':
        # Data.Result 又是JSON字符串
        raw_result = data.get('Data', {}).get('Result', '')
        result = {}
        if raw_result:
            try:
                result = json.loads(raw_result)
            except Exception as e:
                result = {"error": "结果解析失败:" + str(e), "raw": raw_result}

        return {
            'type': 'slider',
            'code': 0,
            'msg': data.get('Msg', ''),
            'success': result.get('success'),
            'validate': result.get('validate'),
            'score': result.get('score'),
            'raw': result
        }
    else:
        return {
            'type': 'unknown',
            'code': data.get('ReturnCode'),
            'msg': data.get('Msg', ''),
            'raw': data
        }
def login_api():
    headers = {
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,ar;q=0.7",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "Origin": "https://exaccount2.eastmoney.com",
        "Pragma": "no-cache",
        "Referer": "https://exaccount2.eastmoney.com/home/Login4?rc=1607457986",
        "RequestVerificationToken": "X25VqYs5DoRsARzY7J1O1nMU5xK217SQEiNvtk872axvd8PYcJv0t1zftrak-TCe431sNHDL3jX0lyZGrmLfmdQKTwk1",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
        "X-Requested-With": "XMLHttpRequest",
        "deviceType": "Web",
        "domainName": "passport2.eastmoney.com",
        "productType": "UserPassport",
        "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\""
    }
    cookies = {
        "qgqp_b_id": "0e62c6084addcd8b73f504ed7097ee3a",
        "websitepoptg_api_time": "1754106536586",
        "st_nvi": "uPvtl1P_7OmOxRkvT4AId7e10",
        "nid": "0ba7bcebb6c437b69474411fda4a96e1",
        "nid_create_time": "1754106537299",
        "gvi": "GxgX_Rp8kWc5suJsQPKMH392b",
        "gvi_create_time": "1754106537299",
        "nid_id": "295676914",
        "st_si": "71678253589540",
        "st_asi": "delete",
        "fullscreengg": "1",
        "fullscreengg2": "1",
        "RequestData": "%7b%22agentPageUrl%22%3a%22https%3a%2f%2fpassport2.eastmoney.com%2fpub%2fLoginAgent%22%2c%22redirectUrl%22%3a%22https%3a%2f%2fwww.eastmoney.com%2f%22%2c%22callBack%22%3a%22LoginCallBack%22%2c%22redirectFunc%22%3a%22PageRedirect%22%2c%22data%22%3a%7b%22domainName%22%3a%22passport2.eastmoney.com%22%2c%22deviceType%22%3a%22Web%22%2c%22productType%22%3a%22UserPassport%22%2c%22version%22%3a%220.0.1%22%7d%2c%22type%22%3anull%7d",
        "__RequestVerificationToken": "-5yJY1j_Dwhwa-HPfbeeHoUKKGZatLfYkSSxw0DUNcdJdYALChwW2a9l3dW0cMUmtvLect4l8E0-bfzw-8swfVBXwCU1",
        "p_origin": "https%3A%2F%2Fpassport2.eastmoney.com",
        "_qct": "e805ea4aa36a412d9b6871ae5a46f84a",
        "_qcu": "163.125.168.209abe6e10e",
        "st_pvi": "59157079925959",
        "st_sp": "2025-08-02%2011%3A48%3A57",
        "st_inirUrl": "https%3A%2F%2Fpassport2.eastmoney.com%2F",
        "st_sn": "2",
        "st_psi": "20250802175428944-0-5141008185"
    }
    url = "https://exaccount2.eastmoney.com/JsonAPI/Login3"
    data = {
        "username": "18320975328",
        "password": "ILuql7J6YmRqd6XqZKiy3Jbo/0cyDw2P4yxISd+htel9FVnt+Ge9nmIFNbenHremxz6mvpcUEThlmOVZz59icdYOaN07dKVk7wIm84ZoOP/XH/0FWD4lZ9HEZjiVxRYEIK0YsSBzW5WPrIka36ejX6zAc9b3QzaDjNK1AlFsJIY=",
        "captconetxt": "93ee681c7403a6a205aa43bb8873c3d5",
        "captvalidate": "dbeabbb0568496d49a28f99098137545"
    }
    response = requests.post(url, headers=headers, cookies=cookies, data=data)

    print(response.text)
    print(response)

def validata(ctxid):
    req= ctx.call("get_validate", ctxid)
    headers = {
        "Accept": "*/*",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,ar;q=0.7",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Pragma": "no-cache",
        "Referer": "https://exaccount2.eastmoney.com/",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
        "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\""
    }
    cookies = {
        "qgqp_b_id": "0e62c6084addcd8b73f504ed7097ee3a",
        "websitepoptg_api_time": "1754106536586",
        "st_nvi": "uPvtl1P_7OmOxRkvT4AId7e10",
        "nid": "0ba7bcebb6c437b69474411fda4a96e1",
        "nid_create_time": "1754106537299",
        "gvi": "GxgX_Rp8kWc5suJsQPKMH392b",
        "gvi_create_time": "1754106537299",
        "st_si": "71678253589540",
        "st_asi": "delete",
        "fullscreengg": "1",
        "fullscreengg2": "1",
        "p_origin": "https%3A%2F%2Fpassport2.eastmoney.com",
        "st_pvi": "59157079925959",
        "st_sp": "2025-08-02%2011%3A48%3A57",
        "st_inirUrl": "https%3A%2F%2Fpassport2.eastmoney.com%2F",
        "st_sn": "5",
        "st_psi": "20250802190712565-0-3336068507"
    }
    url = "https://smartvcode2.eastmoney.com/Titan/api/captcha/Validate"
    params = {
        "callback": "cb",
        "ctxid": ctxid,
        "request": req,
        "_": str(int(time.time() * 1000))
    }
    response = requests.get(url, headers=headers, cookies=cookies, params=params)
    print(response.status_code)
    return parse_validata_response(response.text)
def get_bg(ctxid):

    req= ctx.call("get_req", ctxid)
    print(req)
    headers = {
        "Accept": "*/*",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,ar;q=0.7",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Pragma": "no-cache",
        "Referer": "https://exaccount2.eastmoney.com/",
        "Sec-Fetch-Dest": "script",
        "Sec-Fetch-Mode": "no-cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
        "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\""
    }
    cookies = {
        "qgqp_b_id": "0e62c6084addcd8b73f504ed7097ee3a",
        "websitepoptg_api_time": "1754106536586",
        "st_nvi": "uPvtl1P_7OmOxRkvT4AId7e10",
        "nid": "0ba7bcebb6c437b69474411fda4a96e1",
        "nid_create_time": "1754106537299",
        "gvi": "GxgX_Rp8kWc5suJsQPKMH392b",
        "gvi_create_time": "1754106537299",
        "st_si": "71678253589540",
        "st_asi": "delete",
        "fullscreengg": "1",
        "fullscreengg2": "1",
        "p_origin": "https%3A%2F%2Fpassport2.eastmoney.com",
        "st_pvi": "59157079925959",
        "st_sp": "2025-08-02%2011%3A48%3A57",
        "st_inirUrl": "https%3A%2F%2Fpassport2.eastmoney.com%2F",
        "st_sn": "7",
        "st_psi": "20250803144250671-0-9403247960"
    }
    url = "https://smartvcode2.eastmoney.com/Titan/api/captcha/get"
    params = {
        "callback": "cb",
        "ctxid": ctxid,
        "request": req,
        "_": str(int(time.time() * 1000))
    }
    response = requests.get(url, headers=headers, cookies=cookies, params=params)
    print("请求结果:", response.text)
    if response.status_code != 200:
        print("请求失败，状态码：", response.status_code)
        return None
    return response.text
def get_ctxid():


    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,ar;q=0.7",
        "Cache-Control": "no-cache",
        "Connection": "keep-alive",
        "Pragma": "no-cache",
        "Referer": "https://passport2.eastmoney.com/",
        "Sec-Fetch-Dest": "iframe",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Site": "same-site",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
        "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Microsoft Edge\";v=\"138\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\""
    }
    cookies = {
        "qgqp_b_id": "0e62c6084addcd8b73f504ed7097ee3a",
        "websitepoptg_api_time": "1754106536586",
        "st_nvi": "uPvtl1P_7OmOxRkvT4AId7e10",
        "nid": "0ba7bcebb6c437b69474411fda4a96e1",
        "nid_create_time": "1754106537299",
        "gvi": "GxgX_Rp8kWc5suJsQPKMH392b",
        "gvi_create_time": "1754106537299",
        "nid_id": "295676914",
        "st_si": "71678253589540",
        "st_asi": "delete",
        "fullscreengg": "1",
        "fullscreengg2": "1",
        "RequestData": "%7b%22agentPageUrl%22%3a%22https%3a%2f%2fpassport2.eastmoney.com%2fpub%2fLoginAgent%22%2c%22redirectUrl%22%3a%22https%3a%2f%2fwww.eastmoney.com%2f%22%2c%22callBack%22%3a%22LoginCallBack%22%2c%22redirectFunc%22%3a%22PageRedirect%22%2c%22data%22%3a%7b%22domainName%22%3a%22passport2.eastmoney.com%22%2c%22deviceType%22%3a%22Web%22%2c%22productType%22%3a%22UserPassport%22%2c%22version%22%3a%220.0.1%22%7d%2c%22type%22%3anull%7d",
        "__RequestVerificationToken": "-5yJY1j_Dwhwa-HPfbeeHoUKKGZatLfYkSSxw0DUNcdJdYALChwW2a9l3dW0cMUmtvLect4l8E0-bfzw-8swfVBXwCU1",
        "p_origin": "https%3A%2F%2Fpassport2.eastmoney.com",
        "st_pvi": "59157079925959",
        "st_sp": "2025-08-02%2011%3A48%3A57",
        "st_inirUrl": "https%3A%2F%2Fpassport2.eastmoney.com%2F",
        "st_sn": "4",
        "st_psi": "20250802181413313-0-4988091101",
        "_qct": "5727d74e40da46f1bb18d9fcce4a7c56",
        "_qcu": "163.125.168.209efb6253f"
    }
    url = "https://exaccount2.eastmoney.com/home/Login4"
    params = {
        "rc": "354855057"
    }
    response = requests.get(url, headers=headers, cookies=cookies, params=params)
    html= response.text
    soup= BeautifulSoup(html, 'html.parser')
    ctxid =soup.find('input', id='hdAccountCaptContextId')
    if ctxid is None:
        print("ctxid not found")
        return
    print(response.status_code)
    print(ctxid['value'])
    return ctxid['value']
def download_image(url, path):
    resp = requests.get(url)
    if resp.status_code == 200:
        with open(path, 'wb') as f:
            f.write(resp.content)
        print(f"Saved: {path}")
    else:
        print(f"Failed to download {url}, status: {resp.status_code}")
def extract_captcha_full_urls(response_text):
    """
    解析 JSONP 响应，提取背景图和缺口图完整URL
    :param response_text: str, jsonp格式的接口响应
    :return: (bg_url, slice_url) 两个图片的完整url
    """
    # 1. 提取json内容
    match = re.search(r'cb\((\{.*\})\)', response_text)
    if not match:
        raise ValueError("找不到有效的JSONP内容")
    json_raw = match.group(1)
    data = json.loads(json_raw)

    # 2. 解析嵌套json
    captcha_info_raw = data["Data"]["CaptchaInfo"]
    captcha_info = json.loads(captcha_info_raw)

    # 3. 静态服务器地址和协议
    static_servers = captcha_info.get("static_servers", [])
    protocol = "https://" if captcha_info.get("https", True) else "http://"
    if not static_servers:  # 容错
        raise ValueError("无 static_servers 字段")
    static_server = static_servers[0]
    # 如果服务器字段已含有协议头，则不重复加
    if static_server.startswith("http"):
        base_url = static_server.rstrip('/')
    else:
        base_url = protocol + static_server.rstrip('/')

    # 4. 拼接完整url
    bg_url = base_url + "/" + captcha_info["bg"].lstrip('/')
    slice_url = base_url + "/" + captcha_info["slice"].lstrip('/')
    return bg_url, slice_url

def get_valid_captcha_imgs(ctxid):
    get_bg(ctxid)          # 第一次只初始化
    result= get_bg(ctxid)
 # 第二次获取图片数据
    return result
if __name__ == "__main__":
    ctxid = get_ctxid()
    result = get_valid_captcha_imgs(ctxid)
    print(result)
    # bg_path, slice_path = None, None
    # try:
    #     bg_path, slice_path = extract_captcha_full_urls(result)
    # except Exception as e:
    #     print("提取图片url失败：", e)

    # print("背景图路径:", bg_path)
    # print("缺口图路径:", slice_path)

    # # 判断防止None报错
    # if bg_path and slice_path:
    #     download_image(bg_path, "bg.jpg")
    #     download_image(slice_path, "slice.png")
    # else:
    #     print("没有获取到图片链接，无法下载！")
    # ---使用示例---
    # restore_bg("bg.jpg")